package com.chushouya.product.rabbitmq.sender;

import com.chushouya.common.constant.RabbitMqQueueEnum;
import com.chushouya.common.util.RabbitMQUtil;
import com.general.framework.core.exception.Ex;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * 商品评估解析消息发送器
 * 用于发送商品评估解析消息，调用ResolveEvaluateApiService.resolveEvaluateItem方法
 * 
 * @author chushouya
 */
@Component
@Slf4j
public class ResolveEvaluateMessageSender {

    @Resource
    private RabbitMQUtil rabbitMQUtil;

    /**
     * 发送商品评估解析消息（立即发送）
     * 
     * @param productId 商品ID
     */
    public void sendResolveEvaluateMessage(Long productId) {
        try {
            validateProductId(productId);
            
            log.info("发送商品评估解析消息，商品ID: {}", productId);
            rabbitMQUtil.sendMessage(RabbitMqQueueEnum.PRODUCT_EVALUATE_RESOLVE.getQueueName(), productId);
            log.info("商品评估解析消息发送成功，商品ID: {}", productId);
        } catch (Exception e) {
            log.error("发送商品评估解析消息异常，商品ID: {}, 错误信息: {}", productId, e.getMessage(), e);
            throw new RuntimeException("发送商品评估解析消息失败", e);
        }
    }

    /**
     * 发送商品评估解析消息（延时发送 - 秒）
     * 
     * @param productId 商品ID
     * @param delaySeconds 延时秒数
     */
    public void sendResolveEvaluateMessage(Long productId, int delaySeconds) {
        try {
            validateProductId(productId);
            
            log.info("发送商品评估解析延时消息，商品ID: {}, 延时: {}秒", productId, delaySeconds);
            rabbitMQUtil.sendDelayMessage(
                RabbitMqQueueEnum.PRODUCT_EVALUATE_RESOLVE.getQueueName(), 
                productId, 
                delaySeconds, 
                TimeUnit.SECONDS
            );
            log.info("商品评估解析延时消息发送成功，商品ID: {}, 延时: {}秒", productId, delaySeconds);
        } catch (Exception e) {
            log.error("发送商品评估解析延时消息异常，商品ID: {}, 延时: {}秒, 错误信息: {}", 
                    productId, delaySeconds, e.getMessage(), e);
            throw new RuntimeException("发送商品评估解析延时消息失败", e);
        }
    }

    /**
     * 发送商品评估解析消息（延时发送 - 分钟）
     * 
     * @param productId 商品ID
     * @param delayMinutes 延时分钟数
     */
    public void sendResolveEvaluateMessageDelayMinutes(Long productId, int delayMinutes) {
        try {
            validateProductId(productId);
            
            log.info("发送商品评估解析延时消息，商品ID: {}, 延时: {}分钟", productId, delayMinutes);
            rabbitMQUtil.sendDelayMessage(
                RabbitMqQueueEnum.PRODUCT_EVALUATE_RESOLVE.getQueueName(), 
                productId, 
                delayMinutes, 
                TimeUnit.MINUTES
            );
            log.info("商品评估解析延时消息发送成功，商品ID: {}, 延时: {}分钟", productId, delayMinutes);
        } catch (Exception e) {
            log.error("发送商品评估解析延时消息异常，商品ID: {}, 延时: {}分钟, 错误信息: {}", 
                    productId, delayMinutes, e.getMessage(), e);
            throw new RuntimeException("发送商品评估解析延时消息失败", e);
        }
    }

    /**
     * 发送带类型的商品评估解析消息（立即发送）
     * 
     * @param productId 商品ID
     * @param messageType 消息类型
     */
    public void sendResolveEvaluateMessage(Long productId, String messageType) {
        try {
            validateProductId(productId);
            
            log.info("发送商品评估解析消息，商品ID: {}, 类型: {}", productId, messageType);
            rabbitMQUtil.sendMessage(
                RabbitMqQueueEnum.PRODUCT_EVALUATE_RESOLVE.getQueueName(), 
                messageType, 
                productId
            );
            log.info("商品评估解析消息发送成功，商品ID: {}, 类型: {}", productId, messageType);
        } catch (Exception e) {
            log.error("发送商品评估解析消息异常，商品ID: {}, 类型: {}, 错误信息: {}", 
                    productId, messageType, e.getMessage(), e);
            throw new RuntimeException("发送商品评估解析消息失败", e);
        }
    }

    /**
     * 发送带类型的商品评估解析消息（延时发送）
     * 
     * @param productId 商品ID
     * @param messageType 消息类型
     * @param delay 延时时间
     * @param timeUnit 时间单位
     */
    public void sendResolveEvaluateMessage(Long productId, String messageType, long delay, TimeUnit timeUnit) {
        try {
            validateProductId(productId);
            
            log.info("发送商品评估解析延时消息，商品ID: {}, 类型: {}, 延时: {}{}", 
                    productId, messageType, delay, timeUnit.toString().toLowerCase());
            rabbitMQUtil.sendDelayMessage(
                RabbitMqQueueEnum.PRODUCT_EVALUATE_RESOLVE.getQueueName(), 
                messageType, 
                productId, 
                delay, 
                timeUnit
            );
            log.info("商品评估解析延时消息发送成功，商品ID: {}, 类型: {}, 延时: {}{}", 
                    productId, messageType, delay, timeUnit.toString().toLowerCase());
        } catch (Exception e) {
            log.error("发送商品评估解析延时消息异常，商品ID: {}, 类型: {}, 延时: {}{}, 错误信息: {}", 
                    productId, messageType, delay, timeUnit.toString().toLowerCase(), e.getMessage(), e);
            throw new RuntimeException("发送商品评估解析延时消息失败", e);
        }
    }

    /**
     * 发送商品评估解析重试消息
     * 
     * @param productId 商品ID
     * @param retryCount 重试次数
     */
    public void sendResolveEvaluateRetryMessage(Long productId, int retryCount) {
        try {
            validateProductId(productId);
            
            log.info("发送商品评估解析重试消息，商品ID: {}, 重试次数: {}", productId, retryCount);
            
            String messageType = "EVALUATE_RESOLVE_RETRY_" + retryCount;
            // 重试延时递增：第1次延时30秒，第2次延时60秒，第3次延时120秒
            int delaySeconds = 30 * retryCount;
            rabbitMQUtil.sendDelayMessage(
                RabbitMqQueueEnum.PRODUCT_EVALUATE_RESOLVE.getQueueName(), 
                messageType, 
                productId, 
                delaySeconds, 
                TimeUnit.SECONDS
            );
            log.info("商品评估解析重试消息发送成功，商品ID: {}, 重试次数: {}, 延时: {}秒", 
                    productId, retryCount, delaySeconds);
        } catch (Exception e) {
            log.error("发送商品评估解析重试消息异常，商品ID: {}, 重试次数: {}, 错误信息: {}", 
                    productId, retryCount, e.getMessage(), e);
            throw new RuntimeException("发送商品评估解析重试消息失败", e);
        }
    }

    /**
     * 批量发送商品评估解析消息
     * 
     * @param productIds 商品ID列表
     */
    public void sendResolveEvaluateMessageBatch(Long[] productIds) {
        if (productIds == null || productIds.length == 0) {
            log.warn("商品ID列表为空，跳过批量发送商品评估解析消息");
            return;
        }
        
        log.info("开始批量发送商品评估解析消息，商品数量: {}", productIds.length);
        
        for (int i = 0; i < productIds.length; i++) {
            try {
                // 每个消息间隔一定时间发送，避免处理过于频繁
                int delaySeconds = i * 2; // 每2秒发送一个
                sendResolveEvaluateMessage(productIds[i], delaySeconds);
            } catch (Exception e) {
                log.error("批量发送商品评估解析消息失败，商品ID: {}", productIds[i], e);
            }
        }
        
        log.info("批量发送商品评估解析消息完成，商品数量: {}", productIds.length);
    }

    /**
     * 验证商品ID
     * 
     * @param productId 商品ID
     */
    private void validateProductId(Long productId) {
        if (productId == null || productId <= 0) {
            throw Ex.business("商品ID无效");
        }
    }
}
